using Microsoft.EntityFrameworkCore;
using RAG.Application;
using RAG.Application.Interfaces;
using RAG.Domain.Repositories;
using RAG.Infrastructure;
using RAG.Infrastructure.Data;
using RAG.Infrastructure.Repositories;
using RAG.Application.Services;
using MediatR;
using System.Reflection;
using Serilog;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization.Policy;
using RAG.Api.Middleware;

var builder = WebApplication.CreateBuilder(args);

// 配置Serilog
builder.Host.ConfigureSerilog(builder.Configuration);

// Add services to the container.
builder.Services.AddControllers();

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// JWT认证配置
var jwtSettings = builder.Configuration.GetSection("Jwt");

var secretKey = jwtSettings["SecretKey"] ?? "RAGApiSecretKeyRAGApiSecretKeyRAGApiSecretKeyRAGApiSecretKeyRAGApiSecretKey";
var issuer = jwtSettings["Issuer"] ?? "RAGApi";
var audience = jwtSettings["Audience"] ?? "RAGClient";
var expireMinutes = int.TryParse(jwtSettings["ExpireMinutes"], out var minutes) ? minutes : 120;

// 验证JWT配置
if (string.IsNullOrEmpty(secretKey) || string.IsNullOrEmpty(issuer) || string.IsNullOrEmpty(audience))
{
    throw new InvalidOperationException("JWT配置不完整，请检查appsettings.json中的Jwt配置节");
}

// 配置JWT认证
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        // 验证发行者
        ValidateIssuer = true,
        ValidIssuer = issuer,
        
        // 验证受众
        ValidateAudience = true,
        ValidAudience = audience,
        
        // 验证签名密钥
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)),
        
        // 验证过期时间
        ValidateLifetime = true,
        
        // 允许的时间偏差（5分钟）
        ClockSkew = TimeSpan.FromMinutes(5),
        
        // 验证签名算法
        RequireSignedTokens = true,
        
        // 配置claim类型映射
        NameClaimType = "name",
        RoleClaimType = "role"
    };
    
    // 配置事件处理
    options.Events = new JwtBearerEvents
    {
        OnAuthenticationFailed = context =>
        {
            Console.WriteLine($"JWT认证失败: {context.Exception.Message}");
            return Task.CompletedTask;
        },
        OnTokenValidated = context =>
        {
            // 从token中获取用户信息
            var userId = context.Principal?.FindFirst("sub")?.Value 
                ?? context.Principal?.FindFirst("user_id")?.Value;
            var username = context.Principal?.FindFirst("name")?.Value 
                ?? context.Principal?.FindFirst("username")?.Value;
                
            Console.WriteLine($"JWT令牌验证成功: 用户ID={userId}, 用户名={username}");
            return Task.CompletedTask;
        },
        OnChallenge = context =>
        {
            Console.WriteLine($"JWT认证挑战: {context.Error}, {context.ErrorDescription}");
            return Task.CompletedTask;
        }
    };
});

// 配置授权策略
builder.Services.AddAuthorization(options =>
{
    options.DefaultPolicy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
});

// 添加HttpContextAccessor
builder.Services.AddHttpContextAccessor();

builder.Services.AddInfrastructure(builder.Configuration);
builder.Services.AddApplication(builder.Configuration);

// MediatR配置
builder.Services.AddMediatR(cfg => {
    cfg.RegisterServicesFromAssembly(typeof(IAppUserService).Assembly);
});

// CORS配置
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAll", policy =>
    {
        policy.AllowAnyOrigin()
              .AllowAnyMethod()
              .AllowAnyHeader();
    });
});

var app = builder.Build();

// 使用Serilog请求日志中间件
app.UseSerilogRequestLogging();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseCors("AllowAll");

// 添加认证和授权中间件
app.UseAuthentication();
app.UseAuthorization();

// 添加自定义中间件
app.UseUserActivity();
app.UsePermissionAuthorization();

app.MapControllers();

// 启动应用程序
try
{
    Log.Information("启动 RAG API 应用程序...");
    
    // 验证JWT配置
    var jwtConfig = builder.Configuration.GetSection("Jwt");
    if (!jwtConfig.Exists())
    {
        Log.Error("JWT配置节不存在！");
        throw new InvalidOperationException("JWT配置节不存在");
    }
    
    var configIssuer = jwtConfig["Issuer"];
    var configAudience = jwtConfig["Audience"];
    var configSecretKey = jwtConfig["SecretKey"];
    
    if (string.IsNullOrEmpty(configIssuer) || string.IsNullOrEmpty(configAudience) || string.IsNullOrEmpty(configSecretKey))
    {
        Log.Error("JWT配置不完整！Issuer: {Issuer}, Audience: {Audience}, SecretKey长度: {SecretKeyLength}", 
            configIssuer, configAudience, configSecretKey?.Length ?? 0);
        throw new InvalidOperationException("JWT配置不完整");
    }
    
    Log.Information("JWT配置验证通过");
    
    app.Run();
}
catch (Exception ex)
{
    Log.Fatal(ex, "应用程序启动失败");
}
finally
{
    Log.CloseAndFlush();
}